package com.pctx.pay.alipay.controller;

import com.pctx.alipay.sdk.api.AlipayApiException;
import com.pctx.alipay.sdk.api.AlipayClient;
import com.pctx.alipay.sdk.api.DefaultAlipayClient;
import com.pctx.alipay.sdk.api.domain.AlipayTradeAppPayModel;
import com.pctx.alipay.sdk.api.internal.util.AlipaySignature;
import com.pctx.alipay.sdk.api.request.AlipayTradeAppPayRequest;
import com.pctx.alipay.sdk.api.request.AlipayTradePagePayRequest;
import com.pctx.alipay.sdk.api.request.AlipayTradeWapPayRequest;
import com.pctx.alipay.sdk.api.response.AlipayTradeAppPayResponse;
import com.pctx.alipay.sdk.config.AlipayConfig;
import com.pctx.pay.order.pojo.SystemOrder;
import com.pctx.pay.order.service.SystemOrderService;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Controller
@RequestMapping("alipay")
public class AlipayController {

	private Logger logger = Logger.getLogger(this.getClass());
	@Autowired
	private SystemOrderService systemOrderService;
	@Autowired
	RestTemplate restTemplate;

	/**
	 * 创建系统订单和支付宝PC支付订单
	 * 
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/order/pc")
	public String createPCPayOrder(SystemOrder systemOrder, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
        if (StringUtils.isNotEmpty(systemOrder.getIp())) {
            systemOrder.setIp("127.0.0.1");
        }
        systemOrder.setWay("PC");
        systemOrder.setPay_way("alipay");
        // 创建系统订单
        systemOrderService.createSystemOrder(systemOrder);

		// 获得初始化的AlipayClient
		AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id,
				AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key,
				AlipayConfig.sign_type);

		// 设置请求参数
		AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
		alipayRequest.setReturnUrl(AlipayConfig.return_url);
		if (StringUtils.isNotEmpty(systemOrder.getReturn_url())) {
			alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
		}

		// 商户订单号，商户网站订单系统中唯一订单号，必填
		String out_trade_no = systemOrder.getOrderno();
		// 付款金额，必填
		String total_amount = String.valueOf(systemOrder.getPay_money());
		// 订单名称，必填
		String subject = systemOrder.getSubject();
		// 商品描述，可空
		String body = systemOrder.getBody();

		alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\"," + "\"total_amount\":\"" + total_amount
				+ "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"" + body + "\","
				+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
		// 请求
		String result = alipayClient.pageExecute(alipayRequest).getBody();
		// 输出
		return result;
	}

	/**
	 * 创建系统订单和支付宝APP支付订单
	 * 
	 * @return
	 * @throws Exception
	 */
	@PostMapping("order/app")
	public String createAPPPayOrder( SystemOrder systemOrder, HttpServletRequest req,
			HttpServletResponse resp) throws Exception {
        if (StringUtils.isNotEmpty(systemOrder.getIp())) {
            systemOrder.setIp("127.0.0.1");
        }
        systemOrder.setWay("APP");
        systemOrder.setPay_way("alipay");
        // 创建系统订单
        systemOrderService.createSystemOrder(systemOrder);
		// 实例化客户端
		AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
				AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset,
				AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
		// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
		AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();
		// SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。

		// 商户订单号，商户网站订单系统中唯一订单号，必填
		String out_trade_no = systemOrder.getOrderno();
		// 付款金额，必填
		String total_amount = String.valueOf(systemOrder.getPay_money());
		// 订单名称，必填
		String subject = systemOrder.getSubject();
		// 商品描述，可空
		String body = systemOrder.getBody();

		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		model.setBody(body);
		model.setSubject(subject);
		model.setOutTradeNo(out_trade_no);
		model.setTimeoutExpress("30m");
		model.setTotalAmount(total_amount);
		model.setProductCode("QUICK_MSECURITY_PAY");

		alipayRequest.setBizModel(model);
		alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
		try {
			// 这里和普通的接口调用不同，使用的是sdkExecute
			AlipayTradeAppPayResponse response = alipayClient.sdkExecute(alipayRequest);
			return response.getBody();// 就是orderString
		} catch (AlipayApiException e) {
			logger.error("创建支付宝app支付订单发生异常！", e);
		}
		return null;
	}

	/**
	 * 创建系统订单和支付宝手机网站支付订单
	 * 
	 * @return
	 * @throws Exception
	 */
	@PostMapping("order/mobile")
	public String createMobilePayOrder( SystemOrder systemOrder, HttpServletRequest req,
			HttpServletResponse httpResponse) throws Exception {
        if (StringUtils.isNotEmpty(systemOrder.getIp())) {
            systemOrder.setIp("127.0.0.1");
        }
        systemOrder.setWay("H5");
        systemOrder.setPay_way("alipay");
        // 创建系统订单
        systemOrderService.createSystemOrder(systemOrder);

		AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
				AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset,
				AlipayConfig.alipay_public_key, AlipayConfig.sign_type); // 获得初始化的AlipayClient
		AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();// 创建API对应的request
		alipayRequest.setReturnUrl(AlipayConfig.return_url);
		if (StringUtils.isNotEmpty(systemOrder.getReturn_url())) {
			alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
		}
		alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

		// 商户订单号，商户网站订单系统中唯一订单号，必填
		String out_trade_no = systemOrder.getOrderno();
		// 付款金额，必填
		String total_amount = String.valueOf(systemOrder.getPay_money());
		// 订单名称，必填
		String subject = systemOrder.getSubject();
		alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\",\"total_amount\":\"" + total_amount
				+ "\",\"subject\":\"" + subject + "\",\"product_code\":\"QUICK_WAP_PAY\"}");// 填充业务参数
		String form = "";
		try {
			form = alipayClient.pageExecute(alipayRequest).getBody(); // 调用SDK生成表单
		} catch (AlipayApiException e) {
			logger.error("创建支付宝mobile支付订单发生异常！", e);
		}
		return form;// 直接将完整的表单html输出到页面
	}

	/**
	 * 支付成功后回调
	 * 
	 * @param notify_id
	 * @param out_trade_no
	 * @param trade_status
	 * @param trade_no
	 * @param sign
	 * @param request
	 * @return
	 * @throws UnsupportedEncodingException
	 * @throws AlipayApiException
	 */
	@RequestMapping(value = "/notify")
	public String notify(String notify_id, String out_trade_no, String trade_status, String trade_no, String sign,
			HttpServletRequest request) throws UnsupportedEncodingException, AlipayApiException {
		// 获取支付宝POST过来反馈信息
		Map<String, String> params = new HashMap<String, String>();
		Map<String, String[]> requestParams = request.getParameterMap();
		for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			// 乱码解决，这段代码在出现乱码时使用
			valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
			params.put(name, valueStr);
		}
		boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset,
				AlipayConfig.sign_type); // 调用SDK验证签名

		if (signVerified) {// 验证成功
			if (trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {
				// 商品交易成功之后的业务逻辑代码
				logger.info("支付宝支付回调out_trade_no：" + out_trade_no + "trade_no：" + trade_no);

				SystemOrder systemOrder = new SystemOrder();
				systemOrder.setOrderno(out_trade_no);
				systemOrder = systemOrderService.querySystemOrder(systemOrder);
				// 修改订单状态为成功
				if (null != systemOrder && 1 == systemOrder.getStatus()) {
					systemOrder.setStatus(1);
					systemOrder.setPay_trade_no(trade_no);
					systemOrder.setPay_time(new Date());
					systemOrderService.updateSystemOrder(systemOrder);

					// 调用支付后回调的微服务
					String notify_url = systemOrder.getNotify_url();
					restTemplate.postForEntity(notify_url, systemOrder, String.class);
				}
			}
			return "success";
		} else {
			logger.info("支付宝支付回调>>>>>验签失败>>>>out_trade_no：" + out_trade_no + "trade_no：" + trade_no);
			return "fail";
		}
	}

}